package com.swift.violent.mainstay.config.expand;

import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSON;
import com.github.alenfive.rocketapi.extend.IApiInfoCache;
import com.swift.violent.mainstay.common.constants.Global;
import com.swift.violent.mainstay.config.expand.bean.ApiInfo;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 自定义API缓存
 * The type Default api info cache.
 *
 * @author xuhaifeng
 * @date 2021.1.29 09:56
 */
@Component
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
public class DefaultApiInfoCache implements IApiInfoCache {
    @Resource
    private RedisTemplate<String, Map<String, ApiInfo>> redisTemplate;
    private static final String API_INFO_KEY = "511a11eb6b0958d58c887abbfcafc517";

    @Override
    public void put(com.github.alenfive.rocketapi.entity.ApiInfo apiInfo) {
        final Map<String, ApiInfo> cacheApiInfo = pullNewInterfaceInfo();
        cacheApiInfo.put(buildApiInfoKey(apiInfo),
                JSON.parseObject(JSON.toJSONString(apiInfo), ApiInfo.class));
        removeAll();
        redisTemplate.opsForValue().set(API_INFO_KEY, cacheApiInfo);
    }

    @Override
    public void putAll(Collection<com.github.alenfive.rocketapi.entity.ApiInfo> apiInfoList) {
        final Map<String, ApiInfo> cacheApiInfo = pullNewInterfaceInfo();
        apiInfoList.forEach(apiInfo -> cacheApiInfo.put(buildApiInfoKey(apiInfo),
                JSON.parseObject(JSON.toJSONString(apiInfo), ApiInfo.class)));
        removeAll();
        redisTemplate.opsForValue().set(API_INFO_KEY, cacheApiInfo);
    }

    @Override
    public com.github.alenfive.rocketapi.entity.ApiInfo get(com.github.alenfive.rocketapi.entity.ApiInfo apiInfo) {
        return JSON.parseObject(JSON.toJSONString(pullNewInterfaceInfo().get(buildApiInfoKey(apiInfo))),
                com.github.alenfive.rocketapi.entity.ApiInfo.class);
    }

    @Override
    public Collection<com.github.alenfive.rocketapi.entity.ApiInfo> getAll() {
        return JSON.parseArray(JSON.toJSONString(pullNewInterfaceInfo().values()),
                com.github.alenfive.rocketapi.entity.ApiInfo.class);
    }

    @Override
    public void remove(com.github.alenfive.rocketapi.entity.ApiInfo apiInfo) {
        final Map<String, ApiInfo> cacheApiInfo = pullNewInterfaceInfo();
        cacheApiInfo.remove(buildApiInfoKey(apiInfo));
        removeAll();
        redisTemplate.opsForValue().set(API_INFO_KEY, cacheApiInfo);
    }

    @Override
    public void removeAll() {
        redisTemplate.delete(API_INFO_KEY);
    }

    private String buildApiInfoKey(com.github.alenfive.rocketapi.entity.ApiInfo apiInfo) {
        return apiInfo.getMethod() + Global.NOTS + apiInfo.getPath();
    }

    private Map<String, ApiInfo> pullNewInterfaceInfo() {
        final Map<String, ApiInfo> apiInfoMap =
                redisTemplate.opsForValue().get(API_INFO_KEY);
        final Map<String, ApiInfo> cacheApiInfo =
                new ConcurrentHashMap<>(50);
        if (MapUtil.isNotEmpty(apiInfoMap)) {
            cacheApiInfo.putAll(apiInfoMap);
        }
        return cacheApiInfo;
    }

}
